﻿using System;
using System.Runtime.InteropServices;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace RFEngine.Graphics
{
    [StructLayout(LayoutKind.Sequential)]
    public struct Particle
    {
        #region Fields

        private Vector2 _Position;
        private Color _Color;
        private volatile float _Rotation;
        private volatile float _Scale;

        private volatile float _Age;
        private volatile float _TimeCreated;
        private Vector2 _Velocity;
        private Vector2 _Impulse;

        #region Static Fields

        /// <summary>
        /// Gets or Sets the Vertex Elements of this object.
        /// </summary>
        public static VertexElement[] VertexElements;

        #endregion

        #endregion

        #region Properties

        /// <summary>
        /// Gets the how long this object has left to live
        /// </summary>
        public float Age
        {
            get { return _Age; }
        }

        /// <summary>
        /// Gets or Sets the color of this object.
        /// </summary>
        public Color Color
        {
            get { return _Color; }
            set { _Color = value; }
        }

        /// <summary>
        /// Gets or Sets the position of this object in world space.
        /// </summary>
        public Vector2 Position
        {
            get { return _Position; }
            set { _Position = value; }
        }

        /// <summary>
        /// Gets or Sets the rotation of this object in degrees.
        /// </summary>
        public float Rotation
        {
            get { return _Rotation; }
            set { _Rotation = value; }
        }

        /// <summary>
        /// Gets or Sets the scale of this object.
        /// </summary>
        public float Scale
        {
            get { return _Scale; }
            set { _Scale = MathHelper.Max(value, float.Epsilon); }
        }

        /// <summary>
        /// Gets or Sets the velocity in units in world space per second of this object.
        /// </summary>
        public Vector2 Velocity
        {
            get { return _Velocity; }
            set { _Velocity = value; }                
        }

        /// <summary>
        /// Gets or Sets the amount of momemtum to add to this object in units in world space per second.
        /// This value is cleared after every update.
        /// </summary>
        public Vector2 Impulse
        {
            get { return _Impulse; }
            set { _Impulse = value; }
        }

        #region Static Properties

        /// <summary>
        /// Gets the size of this object in bytes.
        /// </summary>
        public static int SizeInBytes
        {
            get { return sizeof(float) * 5; }
        }

        #endregion

        #endregion

        #region Methods

        #region Constructor(s)

        /// <summary>
        /// Static Implementation Constructs a new instance of this object.
        /// </summary>
        static Particle()
        {
            VertexElements = new VertexElement[]
            {
                new VertexElement(0, 0 , VertexElementFormat.Vector2, VertexElementMethod.Default, VertexElementUsage.Position, 0),
                new VertexElement(0, 8 , VertexElementFormat.Color  , VertexElementMethod.Default, VertexElementUsage.Color   , 0),
                new VertexElement(0, 12, VertexElementFormat.Single , VertexElementMethod.Default, VertexElementUsage.Depth   , 0),
                new VertexElement(0, 16, VertexElementFormat.Single , VertexElementMethod.Default, VertexElementUsage.Depth   , 1)
            };
        }

        #endregion

        #endregion
    }
}
